<?php
defined('_JEXEC') or die('Restricted access');
require_once(JPATH_COMPONENT.DS.'dominio'.DS.'DTOFactory.php');

class SRParserKML2GPX {
	var $_gpx="";
	
	function SRParserKML2GPX(){
		$this->_gpx='<?xml version="1.0"?>
		<gpx
		 version="1.0"
		 creator="kiroltrack"
		 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		 xmlns="http://www.topografix.com/GPX/1/0"
		 xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">';
	}
	
	private function addTime(){
		$this->_gpx=$this->_gpx.'<time>'.date('Y-m-d').'T'.date('G:i:s').'</time>';
	}
	
	private function addNameDesc(){
		$this->_gpx=$this->_gpx.'<trk><name></name><desc></desc><trkseg>';
	}
	private function addWaypoint($lat,$long,$ele,$time,$name){
		$this->_gpx=$this->_gpx.'<wpt lat="'.$lat.'" lon="'.$long.'">
 											<ele>'.$ele.'</ele>
 											<time>'.$time.'</time>
 											<name>'.$name.'</name>
 											<desc><![CDATA['.$name.']]></desc>
										</wpt>';
	}
	private function addSimpleWaypoint($lat,$long){
		$this->_gpx=$this->_gpx.'<trkpt lat="'.$lat.'" lon="'.$long.'">';
										
	}
	private function addElevation($ele){
		$this->_gpx=$this->_gpx.'<ele> '.$ele.'</ele><time>2008-06-21T06:25:46Z</time></trkpt>';
	}
	// por cada waypoint creamos una etiqueta xml en el gpx de salida
	private function parseWP($mvalues,$i) 
	{	
		while($i<count($mvalues)){
			if($mvalues[$i]['tag']=='name'){
				$name=$mvalues[$i]["value"];
			}
			if($mvalues[$i]['tag']=='when'){
				$time=$mvalues[$i]["value"];
			}
			if($mvalues[$i]['tag']=='coordinates'){
				$coordenadas=explode(",",$mvalues[$i]["value"]);
				$long=$coordenadas[0];
				$lat=$coordenadas[1];
				$ele=$coordenadas[2];
			}
			$i++;
		}
		$this->addWaypoint($lat,$long,$ele,$time,$name);
	}



	private function parseLineString($mvalues,$i,$elevation){
 $ElevAnter=0;
		while($i<count($mvalues)){
			if($mvalues[$i]['tag']=='coordinates'){
				$waypoints=explode(' ',$mvalues[$i]["value"]);
				$ele=explode(',',$elevation);
				$ElevAnter=$ele[0];
				for($k=0;$k<count($waypoints);$k++){
					
					$coordinates=explode(',',$waypoints[$k]);
					 
					 echo "Numero de puntos", count($waypoints);
					 
						if(0<count($coordinates[0]) || 0<count($coordinates[1])){
							
							//El primer punto lo posicionamos automaticamente
							
							if ($k <> 0){
								
								//Calculo la distancia entre coordenadas
								$distancia = $this->distance($coordenadaVieja1, $coordenadaVieja2, $coordinates[1], $coordinates[0]);
								
								echo "Distancia->",$distancia;
								
								//Se calcula la diferencia de elevacion
							    $difEle = $ele[$k]- $ElevAnter;
								
								echo "Dif de elevacion->",$difEle;
								
								//Calculamos cual es el porcentaje de elevacion
								$porcentaje= ((100*$difEle)/$distancia);
								
								
								echo "% de elevacion->",$porcentaje," ";
								
								//Se valora cual es el desnivel
								if($porcentaje<10){
									//Si es mejor que 9 se pinta el punto
									$this->addSimpleWaypoint($coordinates[1],$coordinates[0]);
									$this->addElevation($ele[$k]);
									$ElevAnter=$ele[$k];	
								}else{
									
									echo "PUNTO QUE SUPERA EL 9% DE ELEVACION!!!";
									
									$this->addSimpleWaypoint($coordinates[1],$coordinates[0]);
									
									//se le aplica la diferencia de elevación del 9'5%
									
									$kont++;
									echo "Numero de puntos correjidos",$kont;
									
									$ElevCorregida= 9.5*$distancia/100;
									$ElevNueva=$ElevAnter+$ElevCorregida;
									$this->addElevation($ElevNueva);
									$ElevAnter=$ElevNueva;
									
									echo "Se le ha aplicado una elevacion de ", $ElevCorregida, " metros";
									
								}
								
								echo "
								---------------------------------------------
								";
							}

							else {
								
								//En caso de que sea el primer track se pone automaticamente
								$this->addSimpleWaypoint($coordinates[1],$coordinates[0]);
								$this->addElevation($ele[$k]);
								$ElevAnter=$ele[$k];
							}
						
						
							 //Se ponen las coordenadas actuales como viejas
							 $coordenadaVieja1=$coordinates[1];
							 $coordenadaVieja2=$coordinates[0];
							
						}
						
					
				}
			}
			$i++;
		}
	}
	
	private function distance($lat1, $lng1, $lat2, $lng2, $miles = false)
{
	$pi80 = M_PI / 180;
	$lat1 *= $pi80;
	$lng1 *= $pi80;
	$lat2 *= $pi80;
	$lng2 *= $pi80;
 
	$r = 6372.797; // mean radius of Earth in km
	$dlat = $lat2 - $lat1;
	$dlng = $lng2 - $lng1;
	$a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlng / 2) * sin($dlng / 2);
	$c = 2 * atan2(sqrt($a), sqrt(1 - $a));
	$km = $r * $c;
 
	return ($miles ? ($km * 0.621371192) : $km);
}
	function KML2GPX($data,$elevation){
		$this->addTime();
		$this->addNamedesc();
		$xml_parser = xml_parser_create(); 
		xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0);
		xml_parser_set_option($xml_parser, XML_OPTION_SKIP_WHITE, 1);
		xml_parse_into_struct($xml_parser, $data, $outArray);
	    xml_parser_free($xml_parser);
		
	    for ($i=0;$i<count($outArray);$i++){
	    	//cada vez que encuentra un placemark parsea a waypoint de gpx
	    	if($outArray[$i]['tag']=='Placemark'){
	    		$this->parseWP($outArray,$i);
	    	}
	    	//cada vez que encuentra un linestring parsea a waypoints
	    	if($outArray[$i]['tag']=='LineString'){
	    		$this->parseLineString($outArray,$i,$elevation);
				
	    	}
	    }
	    $this->_gpx=$this->_gpx.'</gpx>';
		return $this->_gpx;
	}
}

class SRParserGPX2LineString {
	var $_kml=null;
	
	function SRParserGPX2LineString(){
		$this->_kml='<LineString><coordinates>';
	}
	
	function parseWaypoint($track_point){
		$lat=$track_point['lat'];
		$long=$track_point['lon'];
		
		$this->_kml=$this->_kml.$long.','.$lat.' ';
	}
	function GPX2LineString($file_url){
		//TODO: En plugins/system/plgjoomsocialconnect se ha comentado JString::_strireplace
		//porque causaba bucle infinito
	
		$xml_data = simplexml_load_file($file_url);
		
		foreach($xml_data->trk[0]->trkseg->trkpt as $track_point){
			$this->parseWaypoint($track_point);
		}
	  
	    $this->_kml=$this->_kml.'</coordinates></LineString>';
	    
	    print_r($this->_kml);
	  
		return $this->_kml;
	}
}

class SRGeocoder{
	var $_service_url=null;
	
	function SRGeocoder(){
		$this->_service_url = 'http://maps.google.com/maps/api/geocode/xml';
	}
	
	public function geocode($address){
		$address=preg_replace('/ /', '+', $address);
		
		$curl = curl_init($this->_service_url.'?address='.$address.'&sensor=false');
		curl_setopt($curl, CURLOPT_HEADER, false); 
       	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
       	$curl_response = curl_exec($curl);
       	curl_close($curl);

       	$xml = new SimpleXMLElement($curl_response);
       	$xmlCoords=$xml->result[0]->geometry[0]->location[0];
       	return DTOFactory::getInstance()->getDTOCoordinatesFromXML($xmlCoords);
	}
}